/**
 * 单点修改，子树求和
 */
#include <cstdio>
#include <climits>
#include <algorithm>
using namespace std;

int const SIZE = 1001000;
typedef long long weight_t;

struct edge_t{
    int to;
    int next;
}Edge[SIZE<<1];
int Vertex[SIZE];
int ECnt;
weight_t W[SIZE];

inline void mkEdge(int a,int b){
    Edge[ECnt].to = b;
    Edge[ECnt].next = Vertex[a];
    Vertex[a] = ECnt++;

    Edge[ECnt].to = a;
    Edge[ECnt].next = Vertex[b];
    Vertex[b] = ECnt++;
}

struct node_t{
    int parent;
    int heavy_son;
    int depth;
    int size;
    int top;
    int nid;
    int mdes;//means the maximum index of all descendants
}Node[SIZE] = {{0,0,0,0,0,0}};
int NCnt;
int NewIdx[SIZE];

void dfsHeavyEdge(int node,int parent,int depth){
    Node[node].depth = depth;
    Node[node].parent = parent;
    Node[node].size = 1;

    for(int next=Vertex[node];next;next=Edge[next].next){
        int to = Edge[next].to;
        if ( to == parent ) continue;
        dfsHeavyEdge(to,node,depth+1);
        Node[node].size += Node[to].size;

        if ( Node[to].size > Node[Node[node].heavy_son].size ) Node[node].heavy_son = to;
    }
}

void dfsHeavyPath(int node,int top){
    Node[node].top = top;
    Node[node].mdes = Node[node].nid = NCnt++;
    NewIdx[Node[node].nid] = node;

    if ( 0 == Node[node].heavy_son ) return;
    dfsHeavyPath(Node[node].heavy_son,top);
    Node[node].mdes = max(Node[node].mdes,Node[Node[node].heavy_son].mdes);

    for(int next=Vertex[node];next;next=Edge[next].next){
        int to = Edge[next].to;
        if ( to != Node[node].parent && to != Node[node].heavy_son ){
            dfsHeavyPath(to,to);
            Node[node].mdes = max(Node[node].mdes,Node[to].mdes);
        }
    }
}

int N;
weight_t StSum[SIZE<<2];

inline int lson(int x){return x<<1;}
inline int rson(int x){return lson(x)|1;}

inline void _pushUp(int t){
    StSum[t] = StSum[lson(t)] + StSum[rson(t)];
}

void build(int t,int s,int e){
    if ( s == e ){
        StSum[t] = W[NewIdx[s]];
        return;
    }

    int m = ( s + e ) >> 1;
    build(lson(t),s,m);
    build(rson(t),m+1,e);
    _pushUp(t);
}

void modify(int t,int s,int e,int a,int b,weight_t delta){
    if ( a <= s && e <= b ){
        StSum[t] += delta * ( e - s + 1 );
        return;
    }

    int m = ( s + e ) >> 1;
    if ( a <= m ) modify(lson(t),s,m,a,b,delta);
    if ( m < b ) modify(rson(t),m+1,e,a,b,delta);
    _pushUp(t);
}

weight_t query(int t,int s,int e,int a,int b){
    if ( a <= s && e <= b ){
        return StSum[t];
    }

    weight_t ret = 0LL;
    int m = ( s + e ) >> 1;
    if ( a <= m ) ret += query(lson(t),s,m,a,b);
    if ( m < b ) ret += query(rson(t),m+1,e,a,b);
    return ret;
}

inline void initTree(int n){
    ECnt = NCnt = 1;
    fill(Vertex,Vertex+n+1,0);
    for(int i=1;i<=n;++i) Node[i].heavy_son = 0;
}

inline void modify(int x,weight_t delta){
    modify(1,1,N,Node[x].nid,Node[x].nid,delta);
}

inline void modifySubtree(int x,weight_t delta){
    modify(1,1,N,Node[x].nid,Node[x].mdes,delta);
}

weight_t query(int x){
    return query(1,1,N,Node[x].nid,Node[x].mdes);
}

int M;
int K;

int getInt(){
	int sgn = 1;
	char ch = getchar();
	while( ch != '-' && ( ch < '0' || ch > '9' ) ) ch = getchar();
	if ( '-' == ch ) {sgn = 0;ch=getchar();}

	int ret = (int)(ch-'0');
	while( '0' <= (ch=getchar()) && ch <= '9' ) ret = ret * 10 + (int)(ch-'0');
	return sgn ? ret : -ret;
}
bool read(){
    initTree(N = getInt());
    M = getInt();
    K = getInt();
    for(int i=1;i<=N;++i)scanf("%lld",W+i);

    int a,b;
    for(int i=1;i<N;++i){
        a = getInt();
        mkEdge(a,getInt());
    }

    dfsHeavyEdge(K,0,0);
    dfsHeavyPath(K,K);
    build(1,1,N);
    return true;
}

void proc(){
    int cmd,x;
    weight_t a;
    while(M--){
        cmd = getInt();
        x = getInt();
        if(2==cmd){
            printf("%lld\n",query(x));
        }else{
            modify(x,getInt());
        }
    }
}
int main(){
    //freopen("1.txt","r",stdin);
    read();
    proc();
    return 0;
}

